package com.cyys.modules.wx.service.user;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cyys.common.ql.AR;
import com.cyys.common.services.CyysBaseService;
import com.cyys.common.thirdInterface.wx.WxDecryptDataUtil;
import com.cyys.common.utils.MD5Util;
import com.cyys.common.utils.StringUtil;
import com.cyys.modules.system.service.param.ParamRegionService;
import com.cyys.modules.wx.dao.user.WxUserinfoDao;
import com.cyys.modules.wx.model.user.WxUserinfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
* @description 微信用户Service层
* @author LC
* @date 2020-10-22
*/
@Service("wxUserinfoService")
@Transactional(readOnly = true)
public class WxUserinfoService extends CyysBaseService<WxUserinfoDao, WxUserinfo> {

    @Resource
    ParamRegionService paramRegionService;

    /*@Transactional(readOnly = false)
    public AR wxLogin(WxUserinfo wxUserinfo) throws Exception{
        WxUserinfo entity = getByOpenId(wxUserinfo.getOpenId());
        if(entity == null){ //用户未注册
            //解析省、市、县
            wxUserinfo.setProvince(paramRegionService.getByRegionName(wxUserinfo.getProvince()));
            wxUserinfo.setCity(paramRegionService.getByRegionName(wxUserinfo.getCity()));
            wxUserinfo.setCountry(paramRegionService.getByRegionName(wxUserinfo.getCountry()));
            dao.insert(wxUserinfo);
            return AR.ok(entity,"登录成功");
        }else{
            if(entity.getDisable().equals("1")){
                return AR.failed("用户禁止登录。");
            }
            return AR.ok(entity,"登录成功");
        }
    }*/

    @Transactional(readOnly = false)
    public AR register(String phone, String password, String openId)  throws Exception {
        WxUserinfo wxUserinfo = getByPhone(phone);
        if(wxUserinfo!=null){
            return AR.failed("手机号已存在");
        }
        WxUserinfo user= new WxUserinfo();
        user.setPhone(phone);
        user.setCipher(MD5Util.calcMD5(password));
        user.setOpenId(openId);
        dao.insert(user);
        return AR.ok(user);
    }

    /**
     * 用户登录
     * @Param phone
     * @Param password
     * @Param openId
     **/
    @Transactional(readOnly = false)
    public AR login(String phone, String password, String openId) throws Exception{
        WxUserinfo wxUser = getByPhone(phone);
        if(wxUser == null){
            return AR.failed("账号或密码错误");
        }
        if("1".equals(wxUser.getDisable())){
            return AR.failed("账号已被禁用,请联系管理员");
        }
        //加密对比
        String passwd = MD5Util.calcMD5(password);
        if (!passwd.equals(wxUser.getCipher())) {
            return AR.failed("账号或密码错误");
        } else {
            if(StringUtils.isBlank(wxUser.getOpenId())){
                wxUser.setOpenId(openId);
                dao.updateById(wxUser);
            }
            return AR.ok(wxUser.toResponseEntity(),"登录成功");
        }
    }

    @Transactional(readOnly = false)
    public AR registerByRealPhone(String openId, String encryptDataB64, String sessionKeyB64, String ivB64) throws Exception{
        String phone = decryptPhone(encryptDataB64, sessionKeyB64, ivB64);
        if(StringUtil.isBlank(phone)){
            return  AR.failed("无法获取本机手机号");
        }
        WxUserinfo entity = getByPhone(phone);  //判断手机号是否绑定用户
        if (entity != null) {
            return AR.failed("该手机号已注册，请直接登录");
        }
        WxUserinfo wxUserinfo = new WxUserinfo();
        wxUserinfo.setOpenId(openId);
        wxUserinfo.setPhone(phone);
        wxUserinfo.setDisable("0");
        wxUserinfo.setIsDelete(0);
        wxUserinfo.setDateCreate(new Date());
        dao.insert(wxUserinfo);
        return AR.ok(wxUserinfo.toResponseEntity(), "注册成功。");
    }

    @Transactional(readOnly = false)
    public AR loginByRealPhone(String openId, String encryptDataB64, String sessionKeyB64, String ivB64)throws Exception{
        WxUserinfo wxUserinfo = dao.selectById(openId);
        if(wxUserinfo != null){
            if(StringUtil.isBlank(wxUserinfo.getPhone())){   //有用户无手机号码进行更新
                String phone = decryptPhone(encryptDataB64, sessionKeyB64, ivB64);
                WxUserinfo entity = getByPhone(phone);  //判断手机号是否绑定用户
                if(entity != null){
                    return AR.failed("手机号已绑定其他用户。");
                }
                wxUserinfo.setPhone(phone);
                dao.updateById(wxUserinfo);
                if(wxUserinfo.getDisable().equals("1")){
                    return AR.failed("用户禁止登录。");
                }
                return AR.ok(wxUserinfo.toResponseEntity(),"登录成功。");
            }else{
                if(wxUserinfo.getDisable().equals("1")){
                    return AR.failed("用户禁止登录。");
                }
                return AR.ok(wxUserinfo.toResponseEntity(),"登录成功。");
            }
        }else{  //无注册的手机号
            String phone = decryptPhone(encryptDataB64, sessionKeyB64, ivB64);
            wxUserinfo = getByPhone(phone);
            if(wxUserinfo != null){
                return AR.failed("手机号已绑定其他用户。");
            }
            wxUserinfo.setPhone(decryptPhone(encryptDataB64, sessionKeyB64, ivB64));
            wxUserinfo.setOpenId(openId);
            dao.insert(wxUserinfo);
            return AR.ok(wxUserinfo.toResponseEntity(),"登录成功。");
        }
    }

    /**
     * 解密获取手机号
     * @param encryptDataB64
     * @param sessionKeyB64
     * @param ivB64
     * @return
     * @
     */
    private String decryptPhone( String encryptDataB64, String sessionKeyB64, String ivB64) throws Exception{
        JSONObject jsonObject  = JSON.parseObject(WxDecryptDataUtil.wxDecrypt(encryptDataB64,sessionKeyB64,ivB64));
        return jsonObject.get("purePhoneNumber").toString();
    }

    public WxUserinfo getByPhone(String phone) {
        WxUserinfo entity = new WxUserinfo();
        entity.setPhone(phone);
        return dao.selectOne(new QueryWrapper<>(entity));
    }

    public WxUserinfo getByOpenId(String openId) {
        WxUserinfo entity = new WxUserinfo();
        entity.setOpenId(openId);
        return dao.selectOne(new QueryWrapper<>(entity));
    }

    /**
     * @Description: 修改密码
     * @param userId
     * @param password
     * @param oldPassword
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public AR modifyPwd(String userId, String password, String oldPassword) throws Exception{
        WxUserinfo wxUser = getById(userId);
        if (wxUser == null) {
            return AR.failed("用户不存在");
        }
        String passwd = MD5Util.calcMD5(oldPassword);
        if (!passwd.equals(wxUser.getCipher())) {
            return AR.failed("账号或密码错误");
        } else {
            WxUserinfo entity = new WxUserinfo();
            entity.setId(userId);
            entity.setCipher(MD5Util.calcMD5(password));
            dao.updateById(entity);
            return AR.ok("密码修改成功");
        }
    }

    /**
     * 找回密码
     * @param phone 手机号
     * @param password 新密码
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    public AR findBackPassword(String phone, String password) throws Exception{
        WxUserinfo user = getByPhone(phone);
        if(user == null){
            return AR.failed("手机号未注册");
        }
        WxUserinfo updateObj= new WxUserinfo();
        updateObj.setCipher(MD5Util.calcMD5(password));
        QueryWrapper<WxUserinfo> qw = new QueryWrapper<>();
        qw.eq("phone", phone);
        dao.update(updateObj, qw);
        return AR.ok("找回密码成功");
    }

    /**
     * whm
     * 新用户设置密码
     * @param userId 用户ID
     * @param openid 微信Id
     * @param passwd 密码
     * @return
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public AR setPassword(String userId, String openid, String passwd)throws Exception{
        WxUserinfo wxUser = getById(userId);
        if(wxUser == null) {
            return AR.failed("账号不存在");
        }
        if(wxUser.getCipher()!=null){
            return AR.failed("密码已设置");
        }
        wxUser.setCipher(MD5Util.calcMD5(passwd));
        dao.updateById(wxUser);
        return AR.ok(wxUser.toResponseEntity(), "密码设置成功");
    }
}
